(function(window) {
	// push msg receiver
	function PMsg() {
		var _this = this;
		evt.listenTo('global-update',function(){
			_this.initPublicyWithPh()
		})
		_wlog('init start...');
		this.hotPostPush = new PMsgStore('hot-post' + $apix.getStorage('gid'), true); // 热帖推送
		this.replyPush = new PMsgStore('reply'); // 回复推送
		this.laudPush = new PMsgStore('laud'); // 点赞推送
        this.systemPush = new PMsgStore('system');  //系统推送
        this.taskPush = new PMsgStore('task'); // 点赞推送
		this.listenToLoginEvent();
		this.listenToLogoutEvent();
		this.listenToStorePushMsg();
		_wlog('init done!');

		this.renderPublicy();
		this.listenToGetMsgList();

        updateNoMsgTips();
	}

	PMsg.prototype = {
		clear: function(cb) {
			var doClear = function(store) {
				var unread = store.getUnread();
				store.clear();
				return unread;
			}

			// var unread = doClear(this.hotPostPush) + doClear(this.replyPush) + doClear(this.laudPush);
			// evt.send('gba:decre', {num: unread});

            this.initPublicyWithPh();
            if (app.isLoggedIn()) {
                this.initPrivacyWithPh();
            }

			cb && safeFn(cb.succ)();
		},

		listenToLoginEvent: function() {
			var _this = this;
			evt.listenTo('user-login-ex', function(data) {
				_wlog('on user-login-ex');
				_this.renderPrivacy();
                updateNoMsgTips();

                //请求服务器，更新红点数据
                evt.send('refresh-message-redhot');
			});
		},
		listenToLogoutEvent: function() {
			var _this = this;
			evt.listenTo('user-logout-ex', function(data) {
				_wlog('on user-logout-ex');
				// 退出时，仅消除UI，数据并不清
				// var unread = _this.replyPush.getUnread() + _this.laudPush.getUnread();
				// evt.send('gba:decre', {num: unread});

				_this.clearPrivacy();
                updateNoMsgTips();

                //请求服务器，更新红点数据
                evt.send('refresh-message-redhot');
			});
		},

		listenToStorePushMsg: function() {
			var _this = this;
			var getStore = function(actType) {
				// php code:
				// define('replythread', 1);
				// define('replycomment', 2);
				// define('recommondthread', 3);
				// define('recommondcomment', 4);

				if (1 == actType || 2 == actType) {
					return {store: _this.replyPush, itemId: 'reply-item'};
				} else if (3 == actType || 4 == actType) {
					return {store: _this.laudPush, itemId: 'laud-item'};
				} else if ('pusharticle' == actType) {
					return {store: _this.hotPostPush, itemId: 'hotpost-item'};
                } else if ('system' == actType) {
                    return {store: _this.systemPush, itemId: 'system-item'};
                } else {
                    _wlog('unknown push msg');
                    return undefined;
                }
			}

			var storeMsg = function(store, actType, payload, bHot) {
                // 热门文章: 存储payload；
                if ('pusharticle' == actType) {
					payload.dateline = timestamp();
					store.addMsg(payload);
				} else {
                    // 点赞、回复: 存储payload.action
                    var action = payload.action;
					action.dateline = timestamp();
					store.addMsg(action);
				}

                var id = payload.pushid;
				if (!bHot || id == -1) {
					store.increUnread();
				} else {
					; // hot的，就认为用户已经注意到了，故不需再增加 badge
				}
			}

			var updateItemUI = function(store, itemId) {
				var msg = store.getLastMsg();
				msg.unreadCount = store.getUnread();

			    var html = doT_Render('#tpl-' + itemId, msg);
			    $api.byId(itemId).innerHTML = html;
				sofast();
                utils.triggerLazyImg();
			}

			//	1. 持久存储（后续，用户打开push消息列表，含评论推送列表、点赞推送列表，进行消息展示）
			//	2. 更新列表中“最后一条”为此条
			//  3. badge
			var _this = this;
			evt.listenTo('store-push-msg', function(data) {
                var ps = window.pushIdStore;
                var id = data.payload.pushid;

                if (!ps.isStored(id)) {
                    var actType = data.payload.action.action;
                    var the = getStore(actType);
                    if (obj_being(the)) {
                        var bHot = (data.recvType == 'hot');
                        storeMsg(the.store, actType, data.payload, bHot);
                        ps.setStored(id);

                        // updateItemUI(the.store, the.itemId, bHot);
                        rmNoMsgTips();
                        // if (!bHot || id == -1) {
                            // evt.send('gba:incre', {num: 1});
                        // }
                        evt.send('refresh-message-redhot');
                    }
                } else {
                    _wlog('pushid: ' + id + ' already stored, need not store a 2nd time');
                }
			});
		},

		// （点击入口item）打开列表时，会发此event过来请求数据
		listenToGetMsgList: function() {
			var _this = this;
			var onGetList = function(store, itemId) {
				// 既然已经打开推送列表，那就需要清空unread，并同步清除各相关ba数字
				var unread = store.getUnread();
				if (unread > 0) {
					// item 上的 ba
					var ba = $api.dom($api.byId(itemId), '.unread-count');
					myBa.clear(ba);

					// gba
					evt.send('gba:decre', {num: unread});

					// 清理数据
					store.clearUnread();
				}
				evt.send('cb:get-push-list', store.getMsgList());
			}

			evt.listenTo('get-push-list', function(data) {
				// 注意：若收到此event，那一定是有数据（否则不会有入口item）
				switch (data.msgType) {
					case 'hotpost':
						onGetList(_this.hotPostPush, 'hotpost-item');
						break;
					case 'laud':
						onGetList(_this.laudPush, 'laud-item');
						break;
					case 'reply':
						onGetList(_this.replyPush, 'reply-item');
						break;
                    case 'system':
                        onGetList(_this.systemPush, 'system-item');
                        break;
                    case 'task':
                        onGetList(_this.taskPush, 'task-item');
                        break;
					default:
						elog('no way');
				}
			});
		},

		// 渲染convList中的3个入口item
        renderPublicy: function() {
			this._renderWithLastPush(this.hotPostPush, 'hotpost-item');
        },
        renderPrivacy: function() {
			this._renderWithLastPush(this.laudPush, 'laud-item');
			this._renderWithLastPush(this.replyPush, 'reply-item');
            this._renderWithLastPush(this.systemPush, 'system-item');
            this._renderWithLastPush(this.taskPush, 'task-item');
        },
        initPublicyWithPh: function() {
            this._renderPh('hotpost-item');
        },
        initPrivacyWithPh: function() {
            this._renderPh('reply-item');
            this._renderPh('laud-item');
            this._renderPh('system-item');
            this._renderPh('task-item');
        },

        clearPublicy: function() {
			$api.byId('hotpost-item').innerHTML = '';
        },
        clearPrivacy: function() {
			$api.byId('reply-item').innerHTML = '';
			$api.byId('laud-item').innerHTML = '';
            $api.byId('system-item').innerHTML = '';
            $api.byId('task-item').innerHTML = '';
        },
        clearAll: function() {
            this.clearPublicy();
            this.clearPrivacy();
            updateNoMsgTips();
        },

		_renderWithLastPush: function(store, destId) {
			var list = store.getMsgList();
			var unread = store.getUnread();
			if (list && list.length > 0) {
				var lastOne = list[0];
				lastOne.unreadCount = unread;

			    var html = doT_Render('#tpl-' + destId, lastOne);
			    $api.byId(destId).innerHTML = html;
				sofast(); // 优化 tapmode
                utils.triggerLazyImg();

				// evt.send('gba:incre', {num: unread});
                evt.send('refresh-message-redhot');
			} else {
                this._renderPh(destId);
            }
		},

        _renderPh: function(destId) {
            var data = this._phData(destId);
		    var html = doT_Render('#tpl-' + destId, data);
		    $api.byId(destId).innerHTML = html;
            sofast();
        },

        // ph: placeholder
        _phData: function(type) {
            var common = {
                ph: true,
                unreadCount: 0,
                dateline: 0
            };
            if ('hotpost-item' == type) {
                return extend(common, {
                    title: '今天' + $apix.getStorage('city') + '发生的重大新闻、事件',
                });
            } else if ('reply-item' == type) {
                return extend(common, {
                    title: '城友对你的帖子、评论发表的见解',
                });
            } else if ('laud-item' == type) {
                return extend(common, {
                    title: '城友对你的帖子、评论的点赞',
                });
            }else if ('system-item' == type) {
                return extend(common, {
                    title: '帖子精华、置顶、删帖等系统消息',
                });
            }else if ('task-item' == type) {
                return extend(common, {
                    title: '任务状态变更消息',
                });
            }

            return common;
        },
	}

	function PMsgStore(msgType, bPublic) {
        this._bPublic = bPublic || false;
        this._msgType = msgType;
	}

	PMsgStore.prototype = {
		getUnread: function() {
			var n = $apix.getStorage(this._ukey());
			return n || 0;
		},
		// setUnread: function(n) {
		// 	$apix.setStorage(this._ukey, n);
		// },
		increUnread: function (by) {
			var n = by || 1;

            var ukey = this._ukey();
			var org = $apix.getStorage(ukey);
			if (!obj_being(org)) {
				org = 0;
			}
			$apix.setStorage(ukey, toInt(org) + n);
		},
		clearUnread: function() {
			$apix.rmStorage(this._ukey());
		},

		getMsgList: function() {
			return $apix.getStorage(this._key());
		},
		getLastMsg: function() {
			var list = this.getMsgList();
			if (obj_being(list)) {
				return list[0];  // 最新消息在前边
			} else {
				return undefined;
			}
		},
		addMsg: function(msg) {
            var key = this._key();
			var list = $apix.getStorage(key);
			if (!obj_being(list)) {
				list = [];
			}

			// 最新的放在上边
			list.unshift(msg);
			$apix.setStorage(key, list);
		},

		// 清理消息（以及unread）
		clear: function() {
			$apix.rmStorage(this._key());
			$apix.rmStorage(this._ukey());
		},

        _key: function() {
            return this._makeKey('-push-list');
        },
        _ukey: function() {
            return this._makeKey('-push-unread');
        },

        // @return like: 'u2281-laud-push-list'. if public, will be like: 'u0-hotpost-push-list'
        _makeKey: function(tail) {
            var uid = this._bPublic ? '0' : app.auth.getMyId();
            return ('u' + uid + '-' + this._msgType + tail);
        }
	}

	window.PMsg = PMsg;

	window.fooHotPostItem = function() {
		var one = mockHotPostList[0];
		one.unreadCount = 5;

	    var html = doT_Render('#tpl-hotpost-item', one);
	    $api.byId('hotpost-item').innerHTML = html;
	}
	window.fooLaudItem = function() {
		var one = mockLaudList[0];
		one.unreadCount = 3;
	    var html = doT_Render('#tpl-laud-item', one);
	    $api.byId('laud-item').innerHTML = html;
	}
	window.fooReplyItem = function() {
		var one = mockReplyList[0];
		one.unreadCount = 5;

	    var html = doT_Render('#tpl-reply-item', one);
	    $api.byId('reply-item').innerHTML = html;
	}

	function _log(o) {
		f_log('pmsg', o);
	}
	function _wlog(o) {
		f_wlog('pmsg', o);
	}
	function _elog(o) {
		f_elog('pmsg', o);
	}

})(window);
